package com.yp.infrastructure.shiro.configuration;

import com.yp.infrastructure.shiro.service.ISecurityService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authc.BearerHttpAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


@Slf4j
public class AuthenticationFilter extends BearerHttpAuthenticationFilter {

    public final static String AUTHENTICATION_HEADER = "Authorization";

    private final ISecurityService securityService;

    public AuthenticationFilter(ISecurityService securityService) {
        this.securityService = securityService;
    }

    protected void postHandle(ServletRequest request, ServletResponse response) throws Exception {
        log.debug("post handle.");
    }

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        String token = ((HttpServletRequest) request).getHeader(AUTHENTICATION_HEADER);
        log.debug("token: {}", token);
        return securityService.isAccessAllowed(token);
    }

    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        log.debug("preHandle");
        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
        String origin = httpServletRequest.getHeader("Origin");
        httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpServletResponse.setHeader("Access-control-Allow-Origin", origin);
        httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
        httpServletResponse.setHeader("Vary", "Origin");

        String method = httpServletRequest.getMethod();
        if (method.equals(RequestMethod.OPTIONS.name())) {
            httpServletResponse.setStatus(HttpStatus.OK.value());
            return false;
        }
        return super.preHandle(httpServletRequest, response);
    }
}
